/* eslint-disable no-empty */
/* eslint-disable no-unused-vars */
import serialport from "serialport";
import { ipcRenderer, shell } from "electron";
import _ from "underscore";
import { exec } from "child_process";
import readline from "readline";
import fastXmlParser from "fast-xml-parser";
import he from "he";
import { readFileSync, writeFile } from "fs";
import { textIno, geiArduinoCmd, Official } from "./mian.js";
const Blockly = window.Blockly;

export default class Ele {
  constructor(option = {}) {
    this.COMV = option.COMV;
  }
  /**
   * 保存port
   */
  saveport() { }
  /**
   * 查找port
   */
  static getport() {
    return serialport.list();
  }

  getxml(url) {
    return readFileSync(url, "utf8");
  }

  async cupload(x, vm) {
    let bulid;
    let text;
    const h = vm.$createElement;

    const content_arduino = Blockly.Arduino.workspaceToCode(
      Blockly.mainWorkspace
    );
    let COMV = null;
    const board = "arduino:avr:uno";
    if (x == 1) {
      bulid = "--upload";
      text = vm.$t("download");
      COMV = this.COMV;
      vm.$notify({
        title: vm.$t("Tips"),
        message: h("i", { style: "color: teal" }, `${text}`)
      });
      ipcRenderer.send("closeport-admin", {});
    } else {
      bulid = "--verify";
      text = vm.$t("Compile");
      vm.$notify({
        title: vm.$t("Tips"),
        message: h("i", { style: "color: teal" }, `${text}`)
      });
    }
    //写入代码
    await filters(textIno, content_arduino);
    //生成cmd命令
    return new Promise((res, rej) => {
      let arduino_cmd_string = geiArduinoCmd(bulid, board, COMV);
      //开始执行
      console.log(arduino_cmd_string);
      const pass = exec(arduino_cmd_string);

      const stderr = pass.stderr;
      const stdout = pass.stdout;
      let str = "";
      let timeout = true;
      str = Official;
      var regex = new RegExp("exit", "i");
      const rl = readline.createInterface({
        input: stderr
      });
      const r2 = readline.createInterface({
        input: stdout
      });
      let arduinoLog = document.getElementById("arduinoLog");
      let error = ''
      rl.on("line", input => {
        console.log(input);
        switch (input.trim()) {
          case "exit status 1":
            error = (vm.$t("代码编译出错"));
            break;
          case "An error occurred while uploading the sketch":
            error =(vm.$t("下载出错"));
            break;
          case "Overriding Baud Rate          : 115200":
            x();
            break;
          case "avrdude: stk500_recv(): programmer is not responding":
            pass.kill(0);
            error = (vm.$t("串口连接超时"));
            break;
        }
        str += input + "\r";
        arduinoLog.value = str;
        arduinoLog.scrollTop = arduinoLog.scrollHeight;
      });
      let x = function () {
        return setTimeout(() => {
          pass.kill(0);
          rej(vm.$t("串口连接超时"));
        }, 20000);
      };
      r2.on("line", input => {
        str += input + "\r";
        arduinoLog.value = str;
        arduinoLog.scrollTop = arduinoLog.scrollHeight;
      });
      pass.on("close", code => {
        if (code === 0) {
          res(true);
        } else {
          rej(error);
        }
      });
    });
  }

  static inspectxml(vm) {
    let xmlDom = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace);
    let xml = new XMLSerializer().serializeToString(xmlDom);
    console.log(xml)
    let xmljson = chuankoufy(xml);
    console.log(xmljson)
    if (xmljson.xml[0].block[0] == undefined) {
      xmljson.xml[0].block[0] = xmljson.xml.block;
    }
    let state = this.inspectxmlblock(xmljson.xml[0].block);

    if (state === true) {
      return {
        state: 0
      };
    } else {
      let x = state.toString();
      return {
        state: 1,
        err: vm.$t('电机管脚重复使用', { x })
      };
    }
  }
  static inspectxmlblock(block) {
    console.log(block);
    // 记录管教
    let arr = [];
    let dj = [];
    console.log(block);
    for (let v in block) {
      attr(block[v]);
    }

    function attr(atts) {
      for (let v in atts) {
        if (v === "field") {
          if (
            atts[v][0] != undefined &&
            atts.field[0].attr["@_name"] === "gjall"
          ) {
            arr.push(atts[v][0]["#text"]);
          } else {
            arr.push(atts[v]["#text"]);
          }
        }
        if (v === "next") {
          attr(atts.next.block);
        }
        if (v === "attr" && atts.attr["@_type"] === "controls_dja") {
          dj.push(atts.field[0]["#text"]);
        }
        if (v === "value") {
          if (atts.value[0] == undefined && atts.value.block != undefined) {
            attr(atts.value.block);
          } else if (atts.value[0] != undefined) {
            for (let i in atts.value) {
              if (atts.value[i].block != undefined) {
                attr(atts.value[i].block);
              }
            }
          }
        }
        if (v === "statement") {
          if (
            atts.statement[0] == undefined &&
            atts.statement.block != undefined
          ) {
            attr(atts.statement.block);
          } else if (atts.statement[0] != undefined) {
            for (let i in atts.statement) {
              if (atts.statement[i].block != undefined) {
                attr(atts.statement[i].block);
              }
            }
          }
        }
      }
    }

    arr = _.uniq(arr);
    let arra = [];
    let arrb = [];
    dj = _.intersection(dj, ["A", "B"]);
    for (let v of dj) {
      if (v == "A") {
        arra = _.intersection(arr, [5, 7]);
      }
      if (v == "B") {
        arrb = _.intersection(arr, [6, 8]);
      }
    }
    if (arra.length != 0 || arrb.length != 0) {
      return _.union(arra, arrb);
    } else {
      return true;
    }
  }
}


export function openFile() {
  ipcRenderer.send("open-file", "open-file");
}


export function taobao() {
  shell.openExternal("https://shop253940311.taobao.com/");
}

export function clearLog() { }

export function copyLog() { }

export function website() {
  shell.openExternal("http://www.hterobot.com");
}

export function filters(ino, stdout) {
  return new Promise(function (resolve, reject) {
    writeFile(ino, stdout, err => {
      if (err) {
        return reject(err);
      } else {
        return resolve({
          state: 0
        });
      }
    });
  });
}

ipcRenderer.on("amaximize", (event, arg) => {
  changeDivHeight();
});

export function changeDivHeight() {
  try {
    let height = window.innerHeight;
    document.getElementById("blocklyDiv").style.height =
      height - 48 - 50 + "px";
    document.getElementById("rightCode").style.height = height - 48 - 50 + "px";
    // document.getElementById("code_size").style.height =
    //   (height - 48 - 3) / 1.5 + "px";
    // document.getElementById("logText").style.height =
    //   height - 48 - (height - 48 - 3) / 1.5 - 3 + "px";
  } catch (err) { }
}

export function chuankoufy(xmlData) {
  var options = {
    attributeNamePrefix: "@_",
    attrNodeName: "attr", //default is 'false'
    textNodeName: "#text",
    ignoreAttributes: false,
    ignoreNameSpace: false,
    allowBooleanAttributes: true,
    parseNodeValue: true,
    parseAttributeValue: true,
    arrayMode: true,
    trimValues: true,
    cdataTagName: "__cdata", //default is 'false'
    cdataPositionChar: "\\c",
    localeRange: "", //To support non english character in tag/attribute values.
    attrValueProcessor: a => he.decode(a, { isAttributeValue: true }), //default is a=>a
    tagValueProcessor: a => he.decode(a) //default is a=>a
  };
  return fastXmlParser.parse(xmlData, options);
}

export function chuankoufy3(xmlData, is) {
  var options = {
    attributeNamePrefix: "@",
    attrNodeName: "", //default is 'false'
    textNodeName: "",
    ignoreAttributes: false,
    ignoreNameSpace: false,
    allowBooleanAttributes: true,
    parseNodeValue: true,
    parseAttributeValue: true,
    arrayMode: true,
    trimValues: true,
    cdataTagName: "", //default is 'false'
    cdataPositionChar: "\\c",
    localeRange: "", //To support non english character in tag/attribute values.
    attrValueProcessor: a => he.decode(a, { isAttributeValue: true }), //default is a=>a
    tagValueProcessor: a => he.decode(a) //default is a=>a
  };
  if (is) {
    return fastXmlParser.parse(xmlData, options);
  } else {
    let x = new fastXmlParser.j2xParser(options);
    return x.parse(xmlData);
  }
}
